home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Graphics Plus
/
Graphics Plus.iso
/
msdos
/
raytrace
/
pov
/
source
/
gif.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-07-28
|
7KB
|
238 lines
/****************************************************************************
* gif.c
*
* Gif-format file reader.
*
* NOTE: Portions of this module were written by Steve Bennett and are used
* here with his permission.
*
* from Persistence of Vision Raytracer
* Copyright 1993 Persistence of Vision Team
*---------------------------------------------------------------------------
* NOTICE: This source code file is provided so that users may experiment
* with enhancements to POV-Ray and to port the software to platforms other
* than those supported by the POV-Ray Team. There are strict rules under
* which you are permitted to use this file. The rules are in the file
* named POVLEGAL.DOC which should be distributed with this file. If
* POVLEGAL.DOC is not available or for more info please contact the POV-Ray
* Team Coordinator by leaving a message in CompuServe's Graphics Developer's
* Forum. The latest version of POV-Ray may be found there as well.
*
* This program is based on the popular DKB raytracer version 2.12.
* DKBTrace was originally written by David K. Buck.
* DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
*
*****************************************************************************/
/*
The following routines were borrowed freely from FRACTINT, and represent
a generalized GIF file decoder. This seems the best, most universal format
for reading in Bitmapped images. GIF is a Copyright of Compuserve, Inc.
Swiped and converted to entirely "C" coded routines by AAC for the most
in future portability!
*/
#include "frame.h"
#include "povproto.h"
static IMAGE *Current_Image;
static int Bitmap_Line;
static FILE *Bit_File;
unsigned char *decoderline /* [2049] */ ; /* write-line routines use this */
static IMAGE_COLOUR *gif_colour_map;
static int colourmap_size;
int out_line (pixels, linelen)
unsigned char *pixels;
int linelen;
{
register int x;
register unsigned char *line;
line = Current_Image->data.map_lines[Bitmap_Line++];
for (x = 0; x < linelen; x++)
{
if ((int)(*pixels) > Current_Image->Colour_Map_Size)
{
fprintf (stderr, "Error - GIF Image Map Colour out of range\n");
exit(1);
}
line[x] = *pixels;
pixels++;
}
return (0);
}
#define READ_ERROR -1
int get_byte() /* get byte from file, return the next byte or an error */
{
register int byte;
if ((byte = getc(Bit_File)) != EOF)
return (byte);
else
{
fprintf (stderr, "Premature End Of File reading GIF image\n");
exit (1);
}
return (0); /* Keep the compiler happy */
}
/* Main GIF file decoder. */
void Read_Gif_Image(Image, filename)
IMAGE *Image;
char *filename;
{
register int i, j, status;
unsigned finished, planes;
unsigned char buffer[16];
status = 0;
Current_Image = Image;
if ((Bit_File = Locate_File(filename, READ_FILE_STRING)) == NULL)
{
fprintf (stderr, "Cannot open GIF file %s\n", filename);
exit(1);
}
/* zero out the full write-line */
if ((decoderline = (unsigned char *) malloc (2049)) == NULL)
{
fprintf (stderr, "Cannot allocate space for GIF decoder line\n");
fclose (Bit_File);
exit (1);
}
for (i = 0; i < 2049; i++)
decoderline[i] = (unsigned char) 0;
/* Get the screen description */
for (i = 0; i < 13; i++)
buffer[i] = (unsigned char)get_byte();
if (strncmp((char *) buffer,"GIF",3) || /* use updated GIF specs */
buffer[3] < '0' || buffer[3] > '9' ||
buffer[4] < '0' || buffer[4] > '9' ||
buffer[5] < 'A' || buffer[5] > 'z' )
{
fprintf (stderr, "Invalid GIF file format: %s\n", filename);
fclose(Bit_File);
exit (1);
}
planes = ((unsigned)buffer[10] & 0x0F) + 1;
colourmap_size = (int)(1 << planes);
if ((gif_colour_map = (IMAGE_COLOUR *)
malloc (colourmap_size * sizeof (IMAGE_COLOUR))) == NULL)
{
fprintf (stderr, "Cannot allocate GIF Colour Map\n");
fclose (Bit_File);
exit (1);
}
if ((buffer[10] & 0x80) == 0)
{ /* color map (better be!) */
fprintf (stderr, "Invalid GIF file format: %s\n", filename);
fclose(Bit_File);
exit (1);
}
for (i = 0; i < colourmap_size ; i++)
{
gif_colour_map[i].Red = (unsigned char)get_byte();
gif_colour_map[i].Green = (unsigned char)get_byte();
gif_colour_map[i].Blue = (unsigned char)get_byte();
gif_colour_map[i].Filter = 0;
}
/* Now display one or more GIF objects */
finished = FALSE;
while (!finished)
{
switch (get_byte())
{
case ';': /* End of the GIF dataset */
finished = TRUE;
status = 0;
break;
case '!': /* GIF Extension Block */
get_byte(); /* read (and ignore) the ID */
while ((i = get_byte()) > 0) /* get data len*/
for (j = 0; j < i; j++)
get_byte(); /* flush data */
break;
case ',': /* Start of image object. get description */
for (i = 0; i < 9; i++)
{
if ((j = get_byte()) < 0)
{ /* EOF test (?) */
status = -1;
break;
}
buffer[i] = (unsigned char) j;
}
/* Check "interlaced" bit */
if (j & 0x40)
Error ("Error! Can't deal with interlaced GIF files.");
if (status < 0)
{
finished = TRUE;
break;
}
Image->iwidth = buffer[4] | (buffer[5] << 8);
Image->iheight = buffer[6] | (buffer[7] << 8);
Image->width = (DBL) Image->iwidth;
Image->height = (DBL) Image->iheight;
Bitmap_Line = 0;
Image->Colour_Map_Size = colourmap_size;
Image->Colour_Map = gif_colour_map;
if ((Image->data.map_lines = (unsigned char **)
malloc(Image->iheight * sizeof (unsigned char *)))==NULL)
{
fprintf (stderr, "Cannot allocate memory for picture\n");
exit(1);
}
for (i = 0 ; i < Image->iheight ; i++)
{
if ((Image->data.map_lines[i] = (unsigned char *) malloc(Image->iwidth))==NULL)
{
fprintf (stderr, "Cannot allocate memory for picture\n");
exit(1);
}
}
/* Setup the color palette for the image */
status = decoder ( Image->iwidth); /*put bytes in Buf*/
/* changed param to int */
finished = TRUE;
break;
default:
status = -1;
finished = TRUE;
break;
}
}
free (decoderline);
fclose(Bit_File);
}